/* Autostop
 *
 * Copyright (c) Maciej Gajewski, Grzegorz Latarowski
 * http://code.google.com/p/autostop-automaty-drogowe
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. NO WARRANTY OF ANY KIND is expressed or implied.
 */

/// @file registers.c routines acessing camera registers from userspace
/// using driver's ioctls

// system headers
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>

// kernel/driver
#include <cameradriver.h>

// local
#include "registers.h"

// =========================== read_register =================================================
int read_register( int device, int address )
{
	struct camera_register buffer;		// transport buffer
	
	// prepare transport buffer
	buffer.address	= address;
	buffer.value	= -1;
	
	// go
	ioctl( device,CAMERA_CS0_READ, & buffer );
	
	return buffer.value;
}

// ========================== write_register ==================================================
int write_register( int device, int address, int value )
{
	struct camera_register data;		// transport buffer
	
	// prepare transport buffer
	data.address	= address;
	data.value	= value;
	
	// go
	return ioctl( device, CAMERA_CS0_WRITE, & data );
}

// ================================ read_multi_hibytes ============================================
int read_multi_hibytes( int device, int address, uint8_t* buffer, size_t count )
{
	struct camera_multiple_bytes data;
	
	// prepare info buffer
	data.address	= address;
	data.count		= count;
	data.buffer		= buffer;

	// go
	return ioctl( device, CAMERA_CS0_READ_HIBYTES, & data );
}

// ================================ read_multi_bytes ============================================
int read_multi_bytes( int device, int address, uint8_t* buffer, size_t count )
{
	struct camera_multiple_bytes data;
	
	// prepare info buffer
	data.address	= address;
	data.count		= count;
	data.buffer		= buffer;

	// go
	return ioctl( device, CAMERA_CS0_READ_MULTI, & data );
}

// ================================ write_ccd_register ============================================
int write_ccd_register( int device, int address, int value )
{
	char strbuf[200] = "";
	char* c = 0;
	
	// create command
	snprintf( strbuf, 200, "wrccd %d %u\r", address, value );
	
	// write string
	write_command( device, strbuf );
}

// ================================ write_command ============================================
int write_command( int device, const char* command )
{
	while ( *command )
	{
		write_register( device, CWR_FF, *command );
		command++;
		// TODO check fullxp here, when writing over 60 bytes
	}
}

// eof
